#ifndef _SceneParser_H_
#define _SceneParser_H_

#include <vector>
#include "vectors.h"
#include "camera.h"
#include "light.h"
#include "Triangle.h"
#include "Material.h"
#include "renderConfig.h"
#include "SceneTree.h"

#define MAX_PARSER_TOKEN_LENGTH 100
class SceneParser 
{
public:
	// CONSTRUCTORS, DESTRUCTOR & INITIALIZE
	SceneParser();
	SceneParser(const char *filename);
	~SceneParser();

	// ACCESSORS
	const RenderConfig& getRenderConfig() const { return m_config; }

	Camera* getCamera() { return m_pCamera; }

	Vec3f getBackgroundColor() { return m_background_color; }

	Vec3f getAmbientLight() { return m_ambient_light; }

	int getNumLights() { return m_vpLights.size(); }

	Light* getLight(int i) { 
		assert(i >= 0 && i < m_vpLights.size()); 
		return m_vpLights[i]; }  

	int getNumMaterials() { return m_vpMaterials.size(); }

	Material* getMaterial(int i) { 
		assert(i >= 0 && i < getNumMaterials()); 
		return m_vpMaterials[i]; }  

	SceneTree* getSceneTree() { return m_pSceneTree; }

	void debugMessage();

private:
	// HELPER FUNCTIONS
	void initialize();
	int getToken(char token[MAX_PARSER_TOKEN_LENGTH],FILE *pFile=NULL);
	Vec2f readVec2f (FILE *pFile=NULL);
	Vec3f readVec3f(FILE *pFile=NULL);
	float readFloat(FILE *pFile=NULL);
	int readInt(FILE *pFile=NULL);
	void readString(char* str, FILE *pFile=NULL);

	// PARSING
	void parseFile();
	void parseRenderConfig();
	void parseOrthographicCamera();
	void parsePerspectiveCamera();
	void parseLights();
	void parseBackground();
	void parseMaterials();

	void parseGroup();
	void parseTransform();
	void parseTriangleMesh(Matrix *pMatrix);
	void parseTriangle(Matrix *pMatrix);
	void parseTextureMesh(Matrix *pMatrix);
	void parseSphere();
	void parseTextureTriangle(Matrix *pMatrix);

	// REPRESENTATION
	RenderConfig m_config;
	Camera *m_pCamera;
	Vec3f m_background_color;
	Vec3f m_ambient_light;
	std::vector<Light *> m_vpLights;
	std::vector<Material *> m_vpMaterials;
	SceneTree *m_pSceneTree;

	FILE *m_file;
	Material *m_pCurrent_material;
};

#endif

